package com.ruoyi.galaxy.api;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.config.SpringContextTool;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.galaxy.domain.GalaxyUser;
import com.ruoyi.galaxy.service.impl.GalaxyUserServiceImpl;
import com.ruoyi.galaxy.vo.GalaxyApiResponse;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.service.ISysConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.Map;

/**
 * @author yeoman
 * @date 2025/4/10 20:52
 * @description
 */
public abstract class AbstractGalaxyApi {

    public static final Logger log = LoggerFactory.getLogger(AbstractGalaxyApi.class);

    /**
     * 用户id
     */
    private Long userId;

    /**
     * 设置请求头
     * @return 请求头
     */
    private HttpHeaders buildHttpHeaders() {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Host", "rest-sig.imaitix.com");
        headers.set("accept", "*/*");
        headers.set("sec-fetch-site", "cross-site");
        headers.set("sec-fetch-mode", "cors");
        headers.set("origin", "https://www.galaxyticketing.com");
        headers.set("user-agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 18_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.1.1 Mobile/15E148 Safari/604.1");
        headers.set("site", "m");
        headers.set("referer", "https://www.galaxyticketing.com/");
        headers.set("coeus", "10086");
        headers.set("sec-fetch-dest", "empty");
        headers.set("accept-language", "zh-CN,zh-Hans;q=0.9");
        headers.set("priority", "u=3, i");

        if (this.userId != null) {
            GalaxyUserServiceImpl galaxyUserService = SpringContextTool.getBean(GalaxyUserServiceImpl.class);
            GalaxyUser galaxyUser = galaxyUserService.selectUserById(this.userId);
            if (galaxyUser != null) {
                headers.set("mzoperateid", galaxyUser.getMzOperateId());
                headers.set("x-mz-session", galaxyUser.getxMzSession());

                ISysConfigService sysConfigService = SpringContextTool.getBean(ISysConfigService.class);
                SysConfig config = new SysConfig();
                config.setConfigKey("galaxy");
                List<SysConfig> sysConfigList = sysConfigService.selectConfigList(config);
                if (sysConfigList != null && !sysConfigList.isEmpty()) {
                    String x5sec = sysConfigList.stream().filter(s -> s.getConfigKey().equals("galaxy.x5sec")).findAny().map(SysConfig::getConfigValue).orElse(null);
                    String xXsrfToken = sysConfigList.stream().filter(s -> s.getConfigKey().equals("galaxy.x-xsrf-token")).findAny().map(SysConfig::getConfigValue).orElse(null);
                    if (StringUtils.isBlank(x5sec) || StringUtils.isBlank(xXsrfToken)){
                        throw new ServiceException("x5sec或x-xsrf-token为空");
                    }
                    headers.set("x5sec", x5sec);
                    headers.set("x-xsrf-token", xXsrfToken);
                }
            }
        }

        return headers;
    }

    public <T> GalaxyApiResponse execute(T request, Long userId, GalaxyApiEnum galaxyApiEnum) {
        setUserId(userId);
        HttpEntity<Object> requestEntity;
        HttpHeaders headers = buildHttpHeaders();

        RestTemplate restTemplate = SpringContextTool.getBean(RestTemplate.class);
        ResponseEntity<String> stringResponseEntity = null;
        if (galaxyApiEnum.getHttpMethod() == HttpMethod.GET) {
            requestEntity = new HttpEntity<>(headers);
            Map<String, Object> uriVariables = setUriVariables(request);
            log.info("galaxyApiRequest url:{}, requestEntity:{}, uriVariables:{}", galaxyApiEnum.getUrl(), JSON.toJSON(requestEntity), JSON.toJSON(uriVariables));
            stringResponseEntity = restTemplate.exchange(galaxyApiEnum.getUrl(), galaxyApiEnum.getHttpMethod(), requestEntity, String.class, uriVariables);
            log.info("galaxyApiResponse responseEntity:{}", JSON.toJSON(stringResponseEntity));
        }else if (galaxyApiEnum.getHttpMethod() == HttpMethod.POST) {
            requestEntity = new HttpEntity<>(request, headers);
            log.info("galaxyApiRequest url:{}, requestEntity:{}", galaxyApiEnum.getUrl(), JSON.toJSON(requestEntity));
            stringResponseEntity = restTemplate.exchange(galaxyApiEnum.getUrl(), galaxyApiEnum.getHttpMethod(), requestEntity, String.class);
            log.info("galaxyApiResponse responseEntity:{}", JSON.toJSON(stringResponseEntity));
        }

        if (stringResponseEntity == null) {
            log.error("galaxyApiRequest error, responseEntity is null");
            throw new ServiceException("galaxyApiRequest error, responseEntity is null");
        }

        if (!stringResponseEntity.getStatusCode().is2xxSuccessful()) {
            log.error("galaxyApiRequest status error, status:{}", stringResponseEntity.getStatusCode());
            throw new ServiceException("galaxyApiRequest status error");
        }

        JSONObject body;
        try {
            body = JSONObject.parseObject(stringResponseEntity.getBody());
        }catch (Exception e) {
            log.error("galaxyApiRequest error, body is not json", e);
            throw new ServiceException("galaxyApiRequest error, body is not json.");
        }

        if (body == null) {
            log.error("galaxyApiRequest error, body is null");
            throw new ServiceException("galaxyApiRequest error, body is null");
        }

        if (!body.getBoolean("success")) {
            log.error("galaxyApiRequest error, success is false {}", body.getString("msg"));
            throw new ServiceException("galaxyApiRequest error, success is false. [" + body.getString("msg") + "]");
        }

        if (body.get("data") == null) {
            log.error("galaxyApiRequest error, body data is null");
            throw new ServiceException("galaxyApiRequest error, body data is null. [" + body.getString("msg") + "]");
        }

        return parseResponseData(body.getJSONObject("data"));
    }

    /**
     * 设置用户id
     * @param userId 用户id
     */
    private void setUserId(Long userId) {
        this.userId = userId;
    }

    /**
     * @return userId
     */
    protected Long getUserId() {
        return this.userId;
    }

    /**
     * 设置uriVariables
     * @param request 请求参数
     * @param <T> 请求参数类型
     * @return uriVariables
     */
    protected abstract <T> Map<String, Object> setUriVariables(T request);

    /**
     * 解析响应数据
     * @param data 响应数据
     * @return 解析的响应数据
     */
    protected abstract GalaxyApiResponse parseResponseData(JSONObject data);

}
